package com.bootdo.system.service.impl;

import static com.bootdo.common.utils.ShiroUtils.getUser;
import static com.bootdo.common.utils.ShiroUtils.getUserId;

import java.util.*;

import com.bootdo.quota.dao.QuotaDao;
import com.bootdo.quota.dao.QuotaHistoryDao;
import com.bootdo.quota.domain.QuotaDO;
import com.bootdo.quota.domain.QuotaHistoryDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.bootdo.common.utils.MD5Utils;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.merchant.dao.AgentDao;
import com.bootdo.merchant.dao.MerchantDao;
import com.bootdo.merchant.domain.AgentDO;
import com.bootdo.merchant.domain.MerchantDO;
import com.bootdo.payee.dao.PayeeAgentDao;
import com.bootdo.payee.dao.PayeeDao;
import com.bootdo.payee.domain.PayeeAgentDO;
import com.bootdo.payee.domain.PayeeDO;
import com.bootdo.system.dao.UserDao;
import com.bootdo.system.dao.UserRoleDao;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.domain.UserRoleDO;
import com.bootdo.system.service.UserService;
import com.bootdo.system.vo.UserVO;

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userMapper;
    @Autowired
    UserRoleDao userRoleMapper;
    @Autowired
    AgentDao agentMapper;
    @Autowired
    PayeeAgentDao payeeAgentMapper;
    @Autowired
    MerchantDao merchantMapper;
    @Autowired
    PayeeDao payeeMapper;

    @Autowired
    QuotaDao quotaMapper;

    @Autowired
    QuotaHistoryDao quotaHistoryMapper;



    @Override
//    @Cacheable(value = "user",key = "#id")
    public UserDO get(Long id) {
        List<Long> roleIds = userRoleMapper.listRoleId(id);
        UserDO user = userMapper.get(id);
        user.setRoleIds(roleIds);
        return user;
    }

    @Override
    public List<UserDO> list(Map<String, Object> map) {
        return userMapper.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        if (getUser() != null && getUser().getUserIdCreate() > 0){
            map.put("userIdCreate", getUserId());
        }
        return userMapper.count(map);
    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    @Override
    public int save(UserDO user) {
        int count = userMapper.save(user);
        Long userId = user.getUserId();
        List<Long> roles = user.getRoleIds();
        userRoleMapper.removeByUserId(userId);
        List<UserRoleDO> list = new ArrayList<>();
        for (Long roleId : roles) {
            UserRoleDO ur = new UserRoleDO();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
            if (roleId==64L) {
                //管理员
                QuotaDO quotaDO = new QuotaDO();
                quotaDO.setGmtDate(new Date());
                quotaDO.setActualQuota(0.0);
                quotaDO.setChangeReason("初始额度");
                quotaDO.setChangeType(0);
                quotaDO.setQuota(0.0);
                quotaDO.setStatus(1);
                quotaDO.setUserId(userId);
                quotaMapper.save(quotaDO);

                QuotaHistoryDO quotaHistoryDO = new QuotaHistoryDO();
                quotaHistoryDO.setGmtDate(new Date());
                quotaHistoryDO.setActualQuota(0.0);
                quotaHistoryDO.setChangeReason("初始额度");
                quotaHistoryDO.setChangeType(0);
                quotaHistoryDO.setQuota(0.0);
                quotaHistoryDO.setStatus(1);
                quotaHistoryDO.setVersion(1);
                quotaHistoryDO.setUserId(userId);
                quotaHistoryMapper.save(quotaHistoryDO);

            }
        }
        if (list.size() > 0) {
            userRoleMapper.batchSave(list);
        }
        return count;
    }

    @Override
    public int update(UserDO user) {
        int r = userMapper.update(user);
        Long userId = user.getUserId();
        List<Long> roles = user.getRoleIds();
        userRoleMapper.removeByUserId(userId);
        List<UserRoleDO> list = new ArrayList<>();
        for (Long roleId : roles) {
            UserRoleDO ur = new UserRoleDO();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        if (list.size() > 0) {
            userRoleMapper.batchSave(list);
        }
        return r;
    }

    /**
     * 更新用户密钥
     * @param user
     * @return
     */
    @Override
    public int updateSecret(UserDO user){
        int r = userMapper.update(user);
        return r;
    }

    //    @CacheEvict(value = "user")
    @Override
    public int remove(Long userId) {
        userRoleMapper.removeByUserId(userId);
        return userMapper.remove(userId);
    }

    @Override
    public boolean exit(Map<String, Object> params) {
        boolean exit;
        if(params.get("userId") != null && StringUtils.isNotBlank(String.valueOf(params.get("userId")))){
            List<UserDO> list = userMapper.list(params);
            if (list.size() <= 0){
                Map<String, Object> param = new HashMap<>();
                param.put("mobile", params.get("mobile"));
                exit = userMapper.list(param).size() > 0;
            } else {
                exit = false;
            }
        } else {
            exit = userMapper.list(params).size() > 0;
        }
        return exit;
    }

    @Override
    public Set<String> listRoles(Long userId) {
        return null;
    }

    @Override
    public int resetPwd(UserVO userVO, UserDO userDO) throws Exception {
        if (Objects.equals(userVO.getUserDO().getUserId(), userDO.getUserId())) {
            if (Objects.equals(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdOld()), userDO.getPassword())) {
                userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));
                return userMapper.update(userDO);
            } else {
                throw new Exception("输入的旧密码有误！");
            }
        } else {
            throw new Exception("你修改的不是你登录的账号！");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int resetPwds(UserVO userVO, UserDO userDO) throws Exception {
        if (Objects.equals(userVO.getUserDO().getUserId(), userDO.getUserId())) {
            if (Objects.equals(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdOld()), userDO.getPassword())) {
                userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));

                //获取用户权限
                List<Long> list = userRoleMapper.listRoleId(userDO.getUserId());
                for (Long roleId : list){
                    if (roleId == 60L){
                        //商户代理
                        AgentDO agent = new AgentDO();
                        agent.setUserId(userDO.getUserId());
                        agent.setPassword(userDO.getPassword());
                        agentMapper.update(agent);
                    } else if (roleId == 61L) {
                        //收款代理
                        PayeeAgentDO payeeAgent = new PayeeAgentDO();
                        payeeAgent.setUserId(userDO.getUserId());
                        payeeAgent.setPassword(userDO.getPassword());
                        payeeAgentMapper.update(payeeAgent);
                    } else if (roleId == 62L){
                        //商户
                        MerchantDO merchant = new MerchantDO();
                        merchant.setUserId(userDO.getUserId());
                        merchant.setPassword(userDO.getPassword());
                        merchantMapper.update(merchant);
                    } else if (roleId == 63L) {
                        //收款户
                        PayeeDO payee = new PayeeDO();
                        payee.setUserId(userDO.getUserId());
                        payee.setPassword(userDO.getPassword());
                        payeeMapper.update(payee);
                    }
                }
                return userMapper.update(userDO);
            } else {
                throw new Exception("输入的旧密码有误！");
            }
        } else {
            throw new Exception("你修改的不是你登录的账号！");
        }
    }

    @Override
    public int adminResetPwd(UserVO userVO) throws Exception {
        UserDO userDO = get(userVO.getUserDO().getUserId());
        if ("admin".equals(userDO.getUsername())) {
            throw new Exception("超级管理员的账号不允许直接重置！");
        }
        userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));
        return userMapper.update(userDO);


    }

    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    @Override
    public int batchremove(Long[] userIds) {
        int count = userMapper.batchRemove(userIds);
        userRoleMapper.batchRemoveByUserId(userIds);
        return count;
    }

    @Override
    public int updatePersonal(UserDO userDO) {
        return userMapper.update(userDO);
    }

}
